--[[ 编码: JX-67-10 名称: 站台货品明细-呼出空料箱 作者:HAN 日期:2025-3-10 级别:项目 函数: RunEmptyBoxOutProcess 功能: -- 后台脚本计算入库需要呼出多少空料箱 更改记录: V3.0 HAN 20241231 改成后台线程来处理空料箱呼出计算,因为这个过程是一个比较长的事务,有并发锁表的风险 本次改进的目的就是将这些长事务统一交给后台一个线程排队处理 --]] require ("jx_emptyboxoutplan") --[[ datajson 格式: paramter = { station = station, login = strUserLogin, user_name = strUserName, bs_type = "". bs_no = "" } ]] function RunEmptyBoxOutProcess ( strLuaDEID ) local nRet, strRetInfo, n local paramter, data_json local result = { cntr_count = 0 } nRet, paramter = m3.GetSysDataJson( strLuaDEID ) if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), data_json ) end -- 从入库单这里获取 仓库、库区编码,如果不一样报错 local station = lua.Get_StrAttrValue( paramter.station ) local bs_type = lua.Get_StrAttrValue( paramter.bs_type ) local bs_no = lua.Get_StrAttrValue( paramter.bs_no ) if ( bs_type ~= "Inbound_Wave" ) then mobox.stopProgram( strLuaDEID, "站台货品明细的来源目前只支持入库波次!") return 1 end if ( bs_no == "" ) then mobox.stopProgram( strLuaDEID, "入库波次号不能为空!") return 1 end local in_wave nRet, in_wave = m3.GetDataObjectByKey(strLuaDEID, "Inbound_Wave", "S_WAVE_NO", bs_no ) if ( nRet ~= 0 or in_wave == "") then mobox.stopProgram( strLuaDEID, "无效的入库波次编码'"..bs_no.."'" ) return 1 end local wh_code = lua.Get_StrAttrValue( in_wave.wh_code ) local area_code = lua.Get_StrAttrValue( in_wave.area_code ) if ( wh_code == '' ) then mobox.stopProgram( strLuaDEID, "入库波次对象中仓库属性不能为空!" ) return 1 end if ( area_code == '' ) then mobox.stopProgram( strLuaDEID, "入库波次对象中库区属性不能为空!" ) return 1 end -- 获取需要入库的货品明细,合并相同货品编码 local strCondition local data_objs -- 要联表查询的表 local strTable = "TN_Station_Goods_Detail a LEFT JOIN TN_Material b ON a.S_ITEM_CODE = b.S_ITEM_CODE" -- 要查询的属性 local strAttrs = "a.S_ITEM_CODE, a.S_ITEM_NAME, a.F_QTY, b.F_WEIGHT, b.F_VOLUME, b.S_CELL_TYPE" strCondition = "a.S_STATION_NO = '"..station.."' AND a.N_B_STATE = 0 AND a.S_BS_TYPE = '"..bs_type.."' AND a.S_BS_NO = '"..bs_no.."'" nRet, strRetInfo = mobox.queryMultiTable(strLuaDEID, strAttrs, strTable, 1000, strCondition ) if ( nRet ~= 0 ) then return 2, "queryMultiTable 失败!"..strRetInfo end if ( strRetInfo == '' ) then mobox.stopProgram( strLuaDEID, "没找到需要入库的站台货品!" ) return 1 end local n, item_code, qty, weight, volume, cell_type local detail_attrs local bFind local sg_detail_list = {} -- 站台货品明细 local ret_data = json.decode(strRetInfo) for n = 1, #ret_data do item_code = lua.Get_StrAttrValue( ret_data[n][1] ) item_name = lua.Get_StrAttrValue( ret_data[n][2] ) qty = lua.Get_NumAttrValue( ret_data[n][3] ) weight = lua.Get_NumAttrValue( ret_data[n][4] ) volume = lua.Get_NumAttrValue( ret_data[n][5] ) cell_type = lua.Get_StrAttrValue( ret_data[n][6] ) if ( item_code ~= '' and qty > 0 ) then bFind = false for m = 1, #sg_detail_list do if (sg_detail_list[m].item_code == item_code) then bFind = true sg_detail_list[m].qty = sg_detail_list[m].qty + qty break end end if ( bFind == false ) then local sg_detail = { item_code = item_code, item_name = item_name, qty = qty, weight = weight, volume = volume, cell_type = cell_type } table.insert( sg_detail_list, sg_detail ) end end end -- 计算货品件数,种类 local total_qty = 0 local good_type_num = #sg_detail_list if ( good_type_num == 0 ) then result = { cntr_count = 0 } mobox.returnValue( strLuaDEID, 1, lua.table2str(result) ) return 0 end for n = 1, good_type_num do total_qty = total_qty + sg_detail_list[n].qty end local item_list = {} -- 需要入库的货品 local obj_attrs -- 生成要入库的货品链表 item_list for n = 1, good_type_num do local item = { item_code = sg_detail_list[n].item_code, item_name = sg_detail_list[n].item_name, row = n, volume = sg_detail_list[n].volume, weight = sg_detail_list[n].weight, cell_type = sg_detail_list[n].cell_type, qty = sg_detail_list[n].qty, alloc_qty = 0, cntr_cell_list = {}, empty_cell_type = "", upgrad_cell_index = 0, -- 标记货品开始升格的料格 A = 1, B = 2 ,如果到A还没有合适料格,要从这个料格开始降格 Q = 0, ok = false -- true 表示这个货品已经分配好入库料箱 } table.insert( item_list, item ) end lua.Debug( strLuaDEID, debug.getinfo(1), "超重货品 item_list-->", item_list ) -- 呼出空料箱算法 local ps_cntr_list = {} local ps_detail_list = {} local lane = "" -- 可用巷道 nRet, lane = jx_base.Get_Available_Lane( strLuaDEID, area_code ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), 'jx_base.Get_Available_Lane!'..lane ) end if ( lane == '' ) then mobox.stopProgram( strLuaDEID, "库区里的所有堆垛机状态都是不可用,无法继续呼出料箱!") return 1 end nRet, strRetInfo = JX_EmptyBoxCellOutPlan( strLuaDEID, item_list, wh_code, area_code, lane, station, bs_type, bs_no, ps_cntr_list, ps_detail_list ) if ( nRet ~= 0 ) then if (nRet == 1) then mobox.stopProgram( strLuaDEID, strRetInfo) return 1 else lua.Error( strLuaDEID, debug.getinfo(1), "JX_EmptyBoxCellOutPlan错误: "..strRetInfo) end end -- 站台货品明细 的状态改成 处理中 strCondition = "S_STATION_NO = '"..station.."' AND S_BS_TYPE = '"..bs_type.."' AND S_BS_NO = '"..bs_no.."'" local strSetAttr = "N_B_STATE = 1" -- 1 处理中 nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Station_Goods_Detail", strCondition, strSetAttr ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "更新【站台货品明细】信息失败!"..strRetInfo ) end result = { cntr_count = #ps_cntr_list, cntr_cell_list = ps_detail_list, wave_obj_id = in_wave.id } mobox.returnValue( strLuaDEID, 1, lua.table2str(result) ) return 0 end